package edu.gettysburg.catapp1;

/**
 * ViewMap Activity extends MapActivity and implements LocationListener. 
 * ViewMap is used to track the user's location and to make sure they stay
 * on the tour's path.
 * 
 * @author Patrice Bramble
 * @version 1.0 11/20/2012
 */

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;

public class ViewMap2NoGPS extends MapActivity implements LocationListener{

	private static final long MIN_TIME = 50; //in milliseconds
	private static final float MIN_DISTANCE = 10; // in meters
	private static final int ZOOM = 16;
	private MapView mapView; 
	private MapController mc;
	private List<Overlay> mapOverlays;
	private MapOverlay itemizedoverlay;
	private LocationManager lm;
	private ArrayList<GeoPoint> allPoints;
	private Projection projection;
	private PathOverlay overlay;
	private Path path;
	private MyLocationOverlay mlo;
	@Override
	/**
	 * Sets up the viewmap activity and renders the viewmap_layout
	 * @param savedInstanceState
	 */
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.viewmap_layout); 
        setupMap(); 
 
  
		//new startSetup().execute(URL);
		
		final ProgressDialog pd = ProgressDialog.show(this,"Creating Map","Loading...");
		new Thread(){
			public void run(){
				try{
					sleep(3000);
				}
				catch(Exception e){
					Log.e("tag", e.getMessage());
				}
				pd.dismiss();
			}
		}.start();
//		setupMap();
	}

	/**
	 * This method is called when the map activity is touched
	 * @param m - MotionEvent
	 */
	public boolean onTouchEvent(MotionEvent m){
		return true;
	}
	

//	/**
//	 * Proximity class extends Broadcast Receiver
//	 * @author Patrice Bramble
//	 *
//	 */
//	class Proximity extends BroadcastReceiver{
//		String message = "";
//
//		Proximity(String msg){
//			message = msg;
//		}
//
//		@Override
//		public void onReceive(Context context, Intent intent) {
//			String key = LocationManager.KEY_PROXIMITY_ENTERING;
//			boolean entering = intent.getBooleanExtra(key, false);
//
//			//	Bundle extras = intent.getExtras();
//
//			if(entering) {
//				new AlertDialog.Builder(getBaseContext()).setTitle("Guess What...").setMessage(message).setNeutralButton("Close", null).show();  
//			}
//
//		}
//	}

	/**
	 * Adds proximity alerts such that once the user approaches 
	 * one of the given points, they are alerted with an informative
	 * message. 
	 * @param points
	 */
//	public void addAlerts(ArrayList<GeoPoint> points, ArrayList<String> alts){
//		Intent intent = new Intent(PROX_INTENT);
//		PendingIntent proximityIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
//		IntentFilter filter = new IntentFilter(PROX_INTENT); 
//		for(GeoPoint p : points){
//			lm.addProximityAlert( p.getLatitudeE6()/1E6,p.getLongitudeE6()/1E6,RADIUS,ALERT_EXPIRATION, proximityIntent );
//		}
//		for(String s : alts){
//			registerReceiver(new Proximity(s), filter);
//		}
//	}
	
//	private void displayBubble() {
//
//	    map.removeView(bubble);
//	    bubble.setVisibility(View.GONE);
//
//	    TextView venueName = (TextView) bubble.findViewById(R.id.venuename);
//	    venueName.setText(result.getName());
//
//	    TextView venueTime = (TextView) bubble.findViewById(R.id.venueopenfor);
//	    venueTime.setText("Open for " + result.getOpenFor() + "h");
//
//	    TextView venueFee = (TextView) bubble.findViewById(R.id.venuefee);
//	    venueFee.setText("Entry fee " + result.getPrice());
//
//	    MapView.LayoutParams params = new MapView.LayoutParams(
//	            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 
//	            result.getPoint(), MapView.LayoutParams.BOTTOM_CENTER);
//
//	    bubble.setLayoutParams(params);
//
//	    map.addView(bubble);        
//	    map.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
//
//	    Runnable r = new Runnable() {
//	        public void run() {
//	            Animation fadeIn = AnimationUtils.loadAnimation(activity, R.anim.fadein);
//	            bubble.setVisibility(View.VISIBLE);
//	            bubble.startAnimation(fadeIn);
//	        }
//	    };
//
//	    Projection projection = map.getProjection();
//
//	    Point p = new Point();
//	    projection.toPixels(result.getPoint(), p);
//
//	    p.offset(0, -(bubble.getMeasuredHeight() / 2));
//	    GeoPoint target = projection.fromPixels(p.x, p.y);
//
//
//	    mapController.animateTo(target, r);
//
//	}
	
	//        Location startPos = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
	//        while(startPos == null){
	//        	startPos = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
	//        }
	//        
	//        String url = "google.navigation:q="+startPos.getLatitude()+","+startPos.getLongitude();
	//        Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(url));
	//        intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity");
	//        startActivity(intent);


	/**
	 * Sets up the mapview by making sure GPS is enabled and retrieving and
	 * plotting path and site location
	 */
	public void setupMap(){
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mc=mapView.getController();

		lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

		lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE, this);
		lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

		allPoints = new ArrayList<GeoPoint>();
		//altText = new ArrayList<String>();
		//alerts = new ArrayList<AlertDialog>();
		//alertPoints = new ArrayList<GeoPoint>();

//		altText.add("Welcome to Patrice's Apartment... A Cozy place to call home!!");
//		alertPoints.add(new GeoPoint(39415302,-76766745));

		mapOverlays = mapView.getOverlays();
		projection = mapView.getProjection();
		overlay = new PathOverlay();		

		mlo = new MyLocationOverlay(this,mapView); 
		mlo.enableCompass(); 
		mlo.enableMyLocation();
		
		
//		//Get a LayoutInflater and load up the view we want to display. 
//		//The false in inflater.inflate prevents the bubble View being added to the MapView right away 
//		LayoutInflater inflater = getLayoutInflater(); 
//		
//		LinearLayout bubble = (LinearLayout) inflater.inflate(R.layout.bubble, mapView, false); 
//
//		//Set up the bubble's close button 
//		ImageButton bubbleClose = (ImageButton) bubble.findViewById(R.id.bubbleClose);
//
//		bubbleClose.setOnClickListener(new View.OnClickListener() {
//		
//		    public void onClick(View v) {
//		        Animation fadeOut = AnimationUtils.loadAnimation(ResultsMapResultsDisplayer.this.activity, R.anim.fadeout);
//		        bubble.startAnimation(fadeOut);
//		        bubble.setVisibility(View.GONE);
//		    }
//		});

		Drawable drawable = this.getResources().getDrawable(R.drawable.star);
		itemizedoverlay = new MapOverlay(drawable, this);

		new Thread() {
			@Override
			public void run() {
				try {
					refreshItems();
				} 
				catch (Exception e) {
					e.printStackTrace();
				} 
				finally {
					//finish();
				}
			}
		}.start();

		if(allPoints.size() > 0){
			int index = allPoints.size()/2;
			mc.setCenter(allPoints.get(index));
		}
		//addAlerts(alertPoints, altText);
		mc.setZoom(ZOOM);
		mapOverlays.add(overlay);
		mapOverlays.add(itemizedoverlay);
		mapOverlays.add(mlo); 
	}


    /** 
     * Retrieves all site and path information from an xml feed 
     */ 
    private void refreshItems() { 
        // XML stuff 
        URL url; 
        try { 
            String sitesFeed = "http://cs.gettysburg.edu/~lalvsa01/android/GCLocs.xml"; 
            url = new URL(sitesFeed); 
 
            URLConnection connection; 
            connection = url.openConnection(); 
 
            HttpURLConnection httpConnection = (HttpURLConnection)connection;  
            int responseCode = httpConnection.getResponseCode();
 
            if (responseCode == HttpURLConnection.HTTP_OK) {  
                InputStream in = httpConnection.getInputStream();  
 
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
                DocumentBuilder db = dbf.newDocumentBuilder(); 
 
                // parser 
                Document dom = db.parse(in);       
                Element docEle = dom.getDocumentElement(); 
 
                // get all eqs 
                NodeList nl = docEle.getElementsByTagName("entry"); 
                if (nl != null && nl.getLength() > 0) { 
                    for (int i = 0 ; i < nl.getLength(); i++) { 
                        Element entry = (Element)nl.item(i); 
                        entry.getElementsByTagName("title").item(0); 
                        Element g = (Element)entry.getElementsByTagName("georss:point").item(0); 
                        entry.getElementsByTagName("link").item(0); 
                        String pth = entry.getElementsByTagName("path").item(0).getFirstChild().getNodeValue(); 
 
                        String point = g.getFirstChild().getNodeValue(); 
                        String[] location = point.split(" "); 
                        Double lat = Double.parseDouble(location[0]) * 1e6; 
                        Double lon = Double.parseDouble(location[1]) * 1e6; 
 
                        //Creates GeoPoint and add to itemizedOverlay 
                        GeoPoint loc = new GeoPoint(lat.intValue(), lon.intValue()); 
                        allPoints.add(loc); 
 
                        OverlayItem overlayItem = new OverlayItem(loc, "Latitude: " + loc.getLatitudeE6(), "Longitude: " + loc.getLongitudeE6()); 
                        itemizedoverlay.addOverlay(overlayItem); 
 
                        // creates arraylist of path points 
                        String[] gPaths = pth.split(" "); 
 
                        for (int p = 0; p < gPaths.length/2; p++) { 
                            Double lt = Double.parseDouble(gPaths[p*2]) * 1e6; 
                            Double ln = Double.parseDouble(gPaths[p*2+1]) * 1e6; 
                            allPoints.add(new GeoPoint(lt.intValue(), ln.intValue())); 
                        } 
                    } 
                } 
            } 
        } catch (MalformedURLException e) { 
            e.printStackTrace(); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } catch (ParserConfigurationException e) { 
            e.printStackTrace(); 
        } catch (SAXException e) { 
            e.printStackTrace(); 
        } 
        finally { 
        } 
    } 

	/**
	 * Determines whether or not the GPS is currently activated
	 * @param context - Context for the base application
	 * @return true if the GPS is activated, false, if the GPS is not activated
	 */
	private boolean isGPSActivated(Context context) {
		return ((LocationManager) context.getSystemService(Context.LOCATION_SERVICE)).isProviderEnabled(LocationManager.GPS_PROVIDER)
				&& ((LocationManager) context.getSystemService(Context.LOCATION_SERVICE)).isProviderEnabled(LocationManager.NETWORK_PROVIDER);
	}


	/**
	 * Path Overlay Class
	 * @author Patrice Bramble
	 * Used to draw a path on a mapview
	 */
	class PathOverlay extends Overlay{
		private int color;
		private ArrayList<GeoPoint> points;

		public PathOverlay(int color, ArrayList<GeoPoint> points){
			this.color = color;
			this.points = points;
		}

		public PathOverlay(){
			color = Color.BLUE;
			this.points = allPoints;
		}

		public void draw(Canvas canvas, MapView mapv, boolean shadow){
			super.draw(canvas, mapv, shadow);
			//Configuring the paint brush
			Paint mPaint = new Paint();
			mPaint.setDither(true);
			mPaint.setColor(color);
			mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
			mPaint.setStrokeJoin(Paint.Join.ROUND);
			mPaint.setStrokeCap(Paint.Cap.ROUND);
			mPaint.setStrokeWidth(4);

			path = new Path();
			//path2 = new Path();

			for(int i = 0; i < points.size(); i++){
				GeoPoint gp1 = points.get(i);
				Point p1 = new Point();
				projection.toPixels(gp1,p1);

				if(i <= points.size() - 2){
					GeoPoint gp2 = points.get(i+1);
					Point p2 = new Point();
					projection.toPixels(gp2,p2);
					path.moveTo(p1.x, p1.y);
					path.lineTo(p2.x,p2.y);
				}	
			}
			//						Paint m2Paint = new Paint();
			//						m2Paint.setDither(true);
			//						m2Paint.setColor(Color.RED);
			//						m2Paint.setStyle(Paint.Style.FILL_AND_STROKE);
			//						m2Paint.setStrokeJoin(Paint.Join.ROUND);
			//						m2Paint.setStrokeCap(Paint.Cap.ROUND);
			//						m2Paint.setStrokeWidth(4);
			//						if(InitialSite.SITE_NUM==1) {
			//			
			//							for(int i = 0; i < 6; i++){
			//								GeoPoint gp1 = points.get(i);
			//								Point p1 = new Point();
			//								projection.toPixels(gp1,p1);
			//			
			//								if(i <= points.size() - 2){
			//									GeoPoint gp2 = points.get(i+1);
			//									Point p2 = new Point();
			//									projection.toPixels(gp2,p2);
			//									path2.moveTo(p1.x, p1.y);
			//									path2.lineTo(p2.x,p2.y);
			//								}	
			//							}	
			//			
			//						}
			//						else if(InitialSite.SITE_NUM==2) {
			//			
			//							for(int i = 5; i < 9; i++){
			//								GeoPoint gp1 = points.get(i);
			//								Point p1 = new Point();
			//								projection.toPixels(gp1,p1);
			//			
			//								if(i <= points.size() - 2){
			//									GeoPoint gp2 = points.get(i+1);
			//									Point p2 = new Point();
			//									projection.toPixels(gp2,p2);
			//									path2.moveTo(p1.x, p1.y);
			//									path2.lineTo(p2.x,p2.y);
			//								}	
			//							}
			//						}
			//						else if(InitialSite.SITE_NUM==3) {
			//			
			//							for(int i = 8; i < points.size(); i++){
			//								GeoPoint gp1 = points.get(i);
			//								Point p1 = new Point();
			//								projection.toPixels(gp1,p1);
			//			
			//								if(i <= points.size() - 2){
			//									GeoPoint gp2 = points.get(i+1);
			//									Point p2 = new Point();
			//									projection.toPixels(gp2,p2);
			//									path2.moveTo(p1.x, p1.y);
			//									path2.lineTo(p2.x,p2.y);
			//								}	
			//							}
			//						}
			canvas.drawPath(path, mPaint);
			//canvas.drawPath(path2, m2Paint);
		}

	}
	
	@Override
	public void onConfigurationChanged(Configuration newConfig){
	    //super.onConfigurationChanged(newConfig);
	    //setupLayout();
	}


	public void onLocationChanged(Location location) {
		if (location != null) {
			Double lat = location.getLatitude() * 1e6;
			Double lng = location.getLongitude() * 1e6;
			GeoPoint gp = new GeoPoint(lat.intValue(), lng.intValue());	
			mc.animateTo(gp);
			mc.setCenter(gp);
		}
	}

	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub

	}

	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub

	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	protected void onStart(){
		super.onStart();
		//Checks to see if GPS is enable
		//If not, leads user to enabling GPS
		if(!isGPSActivated(this)){
			new AlertDialog.Builder(this).setMessage("GPS is required.").setCancelable(false).setPositiveButton("Enable GPS", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {
					startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
				}
			}).setNegativeButton("Exit", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {
					dialog.cancel();
					finish();
				}
			}).create().show();
		}
	}
		
		protected void onResume(){
			super.onResume();
			if(!isGPSActivated(this)){
				new AlertDialog.Builder(this).setMessage("GPS is required.").setCancelable(false).setPositiveButton("Enable GPS", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS),1);
					}
				}).setNegativeButton("Exit", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						dialog.cancel();
						finish();
					}
				}).create().show();
			}
			lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5L, 1f, this);
			mlo.enableMyLocation();
		}
		
		protected void onPause(){
			super.onPause();
			lm.removeUpdates(this);
			mlo.disableMyLocation();
		}
	//	
	//	protected void onDestroy(){
	//		lm.removeUpdates(this);
	//		mlo.disableMyLocation();
	//	}

}